// Decompiled with JetBrains decompiler
// Type: StringKeyMetaBase`2
// Assembly: FMCommon, Version=1.0.8663.21262, Culture=neutral, PublicKeyToken=null
// MVID: 52773074-FB09-4BA0-8FA9-4782D11D6C17
// Assembly location: /Users/mac/work/RiverGame/com.rivergame.fmframework/Runtime/Plugins/FMCommon.dll

using FibMatrix;
using FibMatrix.Config;
using System;
using System.Collections.Generic;

public class StringKeyMetaBase<T, K> : IMetaImpl<string>, IMeta
  where T : class, IMetaImpl<string>
  where K : class, IMetaBuilder, new()
{
  private static Dictionary<string, T> _metaMap;
  private static IMetaBuilder _metaBuilder;
  private static IMetaItemSetImpl<string> _cachedMetaItemSet;
  protected static int _id_key2Id;

  public static void GenerateMeta(IMetaItemSet iter, bool delayMode)
  {
    StringKeyMetaBase<T, K>.DoGenerateMeta(iter, delayMode);
  }

  private static void DoGenerateMeta(IMetaItemSet iter, bool delayMode)
  {
    StringKeyMetaBase<T, K>._id_key2Id = iter.PropName2Id("id");
    StringKeyMetaBase<T, K>._metaMap = new Dictionary<string, T>(iter.totalCount);
    if (delayMode)
    {
      StringKeyMetaBase<T, K>._cachedMetaItemSet = iter as IMetaItemSetImpl<string>;
    }
    else
    {
      while (iter.MoveNext())
      {
        IMetaKeyValueCollection current = iter.Current;
        string str = current.ReadString(StringKeyMetaBase<T, K>._id_key2Id, (string) null);
        if (!StringKeyMetaBase<T, K>._metaMap.ContainsKey(str))
        {
          StringKeyMetaBase<T, K>.AddMeta(str, current, out T _);
        }
        else
        {
          Type type = typeof (T);
          Logger.Warning(((object) type != null ? type.ToString() : (string) null) + " meta id " + str + " duplicated!");
        }
      }
    }
  }

  private static void AddMeta(string id, IMetaKeyValueCollection rawProperties, out T meta)
  {
    if (StringKeyMetaBase<T, K>._metaBuilder == null)
      StringKeyMetaBase<T, K>._metaBuilder = (IMetaBuilder) new K();
    meta = StringKeyMetaBase<T, K>._metaBuilder.Create() as T;
    meta.UpdatePropertyFrom(rawProperties);
    StringKeyMetaBase<T, K>._metaMap.Add(id, meta);
  }

  public static bool HasMeta(string id)
  {
    if (StringKeyMetaBase<T, K>._metaMap != null && StringKeyMetaBase<T, K>._metaMap.ContainsKey(id))
      return true;
    return StringKeyMetaBase<T, K>._cachedMetaItemSet != null && StringKeyMetaBase<T, K>._cachedMetaItemSet.HasMetaProps(id);
  }

  public static T GetMeta(string id)
  {
    T meta = StringKeyMetaBase<T, K>.DoGetMeta(id, false);
    if ((object) meta == null)
      Logger.Error(string.Format("Meta [{0}] does not have an id: {1}", (object) typeof (T), (object) id));
    return meta;
  }

  public static T EnsureGetMeta(string id)
  {
    return StringKeyMetaBase<T, K>.DoGetMeta(id, true);
  }

  public static T FastGetMeta(string id)
  {
    T obj = default (T);
    StringKeyMetaBase<T, K>._metaMap.TryGetValue(id, out obj);
    return obj;
  }

  public static int GetMetaTotalCount()
  {
    return StringKeyMetaBase<T, K>._metaMap == null ? 0 : StringKeyMetaBase<T, K>._metaMap.Count;
  }

  private static T DoGetMeta(string id, bool logError)
  {
    T meta = default (T);
    if (StringKeyMetaBase<T, K>._metaMap != null && !StringKeyMetaBase<T, K>._metaMap.TryGetValue(id, out meta))
    {
      if (StringKeyMetaBase<T, K>._cachedMetaItemSet != null)
      {
        IMetaKeyValueCollection metaPropsById = StringKeyMetaBase<T, K>._cachedMetaItemSet.GetMetaPropsById(id);
        if (metaPropsById != null)
        {
          StringKeyMetaBase<T, K>.AddMeta(id, metaPropsById, out meta);
          if (StringKeyMetaBase<T, K>._metaMap.Count == StringKeyMetaBase<T, K>._cachedMetaItemSet.totalCount)
          {
            StringKeyMetaBase<T, K>._cachedMetaItemSet.Dispose();
            StringKeyMetaBase<T, K>._cachedMetaItemSet = (IMetaItemSetImpl<string>) null;
          }
        }
      }
      if ((object) meta == null & logError)
        Logger.Error(string.Format("Meta [{0}] does not have an id: {1}", (object) typeof (T), (object) id));
    }
    return meta;
  }

  public static IEnumerator<T> GetMetaEnumerator()
  {
    if (StringKeyMetaBase<T, K>._cachedMetaItemSet != null)
      throw new Exception("delay模式下请不要遍历meta，如果是必须操作请将此meta的解析设为非delay模式");
    return (IEnumerator<T>) StringKeyMetaBase<T, K>._metaMap.Values.GetEnumerator();
  }

  public virtual string id { get; set; }

  public virtual void UpdatePropertyFrom(IMetaKeyValueCollection properties)
  {
    throw new NotImplementedException();
  }
}
